package com.owg.jigsaw;

import java.util.Queue;

import com.owg.jigsaw.javafx.FXCell;
import com.owg.jigsaw.javafx.FXUtil;
import com.owg.jigsaw.slots.Slot;

import javafx.geometry.Point2D;
import javafx.scene.Group;
import javafx.scene.layout.Pane;
import owg.util.data.PFieldImmutable;
import owg.util.data.PFieldList;
import owg.util.data.property.Property;

public class WCell implements WContainer<Slot>
{	
	public final Property<Group> contentPane = new Property<>(Group.class, null);

	public final PFieldList<Slot> southSlots = new PFieldList<Slot>(this, Slot.class, 0, -1);
	public final PFieldList<Slot> eastSlots = new PFieldList<Slot>(this, Slot.class, 0, -1); 
	
	public final int x,y;
	public final WBlock block;

	private FXCell ui;
	
	WCell(int x, int y, WBlock block)
	{
		this.x = x;
		this.y = y;
		this.block = block;
	}
	/**
	 * Use the indicated Group as this cell's "content pane". 
	 * <br/><br/>
	 * The content pane is displayed in the center of the cell and may contain objects such as a label or a text field.
	 * Note that only Group objects are supported because the different JavaFX Nodes perform layout differently, use 
	 * layout information in completely different ways, and supply different layout information. There is no generally 
	 * acceptable way of determining a Node's preferred size. The supplied Group must be self-resizing so that its
	 * {@link Region#boundsInLocalProperty()} changes to fit its best size at any given time.
	 */
	public void installContentPane(Group n)
	{
		contentPane.set(n);
	}
	@Override
	public void pFieldChange(PFieldImmutable<? extends Slot> field, Slot newChild, int index)
	{
		if(newChild.isMultiSlot)
		{
			//Slot-lists depend on the cell to the east or south for their visuals.
			//Trigger the creation of the next cell:
			if(field == southSlots)
				block.getCell(x, y+1);
			else if(field == eastSlots)
				block.getCell(x+1, y);
		}
	}
	@Override
	public WContainer<?> getParent()
	{
		return block;
	}
	@Override
	public WRoot getRoot()
	{
		return block.getRoot();
	}
	@Override
	public Pane getUI()
	{
		if(ui == null)
			ui = new FXCell(this);
		return ui;
	}
	/**Get the block that this cell is associated with. This value is final and will not change.*/
	public WBlock getBlock()
	{
		return block;
	}
	@Override
	public void putTargetSlots(Queue<Slot> sq)
	{
		for(Slot s : southSlots)
			s.putTargetSlots(sq);
		for(Slot s : eastSlots)
			s.putTargetSlots(sq);
	}	
	@Override
	public WBlock getBlockAt(Point2D localPoint)
	{
		for(Slot s : southSlots)
		{
			Pane slotUI = s.getUI();
			Point2D slotPoint = FXUtil.fromTo(this.ui, slotUI, localPoint);
			WBlock blk = s.getBlockAt(slotPoint);
			if(blk != null)
				return blk;
		}
		for(Slot s : eastSlots)
		{
			Pane slotUI = s.getUI();
			Point2D slotPoint = FXUtil.fromTo(this.ui, slotUI, localPoint);
			WBlock blk = s.getBlockAt(slotPoint);
			if(blk != null)
				return blk;
		}
		return null;
	}
	/**Called when the parent block will no longer be available to the user, typically when moved to the trash can.*/
	public void dispose()
	{
		for(Slot s : southSlots)
		{
			s.dispose();
		}
		for(Slot s : eastSlots)
		{
			s.dispose();
		}
	}
}
